package com.xyz.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

public class DateUtils {

   private static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; // 格式化模式
    /**
     * 根据给定的日期字符串和时间字符串创建一个Date对象。
     *
     * @param dateString 日期字符串，格式为 "yyyy-MM-dd"
     * @param timeString 时间字符串，格式为 "HH:mm:ss.SSS"
     * @return 包含指定日期和时间的Date对象
     * @throws ParseException 如果日期或时间字符串的格式不正确
     */
    public static Date createDate(String dateString, String timeString) throws ParseException {
        // 创建日期和时间的解析器
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SSS");

        // 解析日期字符串为Date对象
        Date date = dateFormat.parse(dateString);

        // 解析时间字符串为Calendar对象（因为我们需要设置时间到已经解析出的日期上）
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        java.util.Date time = timeFormat.parse(timeString);

        // 由于timeFormat.parse()返回的是一个Date对象，我们需要将其时间部分提取出来并设置到calendar上
        // 但由于我们已知timeString的格式，我们可以直接通过字符串解析来获取小时、分钟、秒和毫秒
        // 然而，为了简单起见，并且避免时区转换的问题（尽管在这个特定情况下可能不是问题），
        // 我们可以将time Date对象的时间部分设置为calendar的时间（这假设time Date对象的日期部分被忽略）
        // 一种更简单且直接的方法是使用另一个Calendar对象来解析timeString，并从中提取时间字段

        // 但为了保持方法的直接性和清晰性，并且因为我们已经知道timeString的格式是正确的，
        // 我们可以简单地使用以下技巧：将time Date对象的时间（从午夜开始计算的毫秒数）加到calendar的午夜时间上
        // 这通常不是最佳实践，因为它依赖于Date对象内部的毫秒表示，但在这个特定情况下是可行的
        // 然而，为了更准确地处理，我们将使用字段设置方法

        // 更准确的方法：使用Calendar解析timeString并设置字段（如下所示）
        Calendar timeCalendar = Calendar.getInstance();
        timeCalendar.setTime(timeFormat.parse(timeString)); // 这里实际上会忽略日期部分，只关心时间

        // 设置calendar对象的时间字段
        calendar.set(Calendar.HOUR_OF_DAY, timeCalendar.get(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, timeCalendar.get(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, timeCalendar.get(Calendar.SECOND));
        calendar.set(Calendar.MILLISECOND, timeCalendar.get(Calendar.MILLISECOND));

        // 获取最终的Date对象
        return calendar.getTime();

        // 注意：上面的代码有些冗长，因为我们需要从timeString中解析时间并单独设置每个字段。
        // 在实际应用中，如果确定timeString的格式总是正确的，并且不关心时区问题，
        // 可以考虑使用更简洁但可能不太安全的方法（例如，通过计算午夜到指定时间的毫秒差并添加到calendar的午夜时间上）。
    }



    /**
     * 将时间戳转换为格式化的日期字符串
     *
     * @param timestamp 待转换的时间戳（秒或毫秒）
     * @param pattern   日期格式
     * @return 格式化后的日期字符串
     */
    public static String convertTimestampToFormattedDate(long timestamp, String pattern) {
        // 如果时间戳是以秒为单位，则直接使用。如果是毫秒，则需要转换。
        LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault());

        // 定义格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

        // 格式化时间
        return dateTime.format(formatter);
    }

    public static String convertTimestampToFormattedDate(long timestamp) {
      return convertTimestampToFormattedDate(timestamp, PATTERN);
    }

    public static void main(String[] args) {
        try {
            String dateString = "2024-08-28";
            String timeString = "23:23:23.999";
            Date date = createDate(dateString, timeString);
            System.out.println(date); // 这将打印出Date对象的默认toString表示，可能不是人类可读的格式

            // 为了更清晰地查看结果，我们可以将Date对象格式化为字符串
            SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
            String formattedDate = dateTimeFormat.format(date);
            System.out.println("Formatted Date: " + formattedDate); // 这将打印出 "2024-08-28 23:23:23.999"

        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}